package entity.lianxi.demo11;

import java.lang.reflect.Field;

public class BeanUtil {
     //1、设置何意对象的属性值
    public static void setProperty(Object bean, String propertyName, Object value){
        //获取操作类的Class 对象
        Class<?> clazz = bean.getClass();
        //获取：Bean 的字段对应的对象
        try {
            Field fields = clazz.getDeclaredField(propertyName);

            //第三：开放访问权限
            fields.setAccessible(true);

            //第四:条用set XX方法，实现初始化工作
            fields.set(bean,value);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException("未知字段",e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("初始化失败",e);
        }
    }

    //2、获取任意对象的属性值
    public static Object getProperty(Object bean, String propertyName){
        //获取操作类的Class 对象
        Class<?> clazz = bean.getClass();
        //获取：Bean 的字段对应的对象
        try {
            Field fields = clazz.getDeclaredField(propertyName);

            //第三：开放访问权限
            fields.setAccessible(true);

            //第四:调用，获取字段数据
            return fields.get(bean);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException("未知字段",e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("初始化失败",e);
        }
    }

    //3、复制某个对象的属性值到另一个对象中
    public static void copyProperties(Object sourceBean, Object targetBean){
        // 第一：获取要操作类的 Class 对象
        Class<?> sourceBeanClass = sourceBean.getClass();
        Class<?> targetBeanClass = targetBean.getClass();

        // 第二：基于 Class 对象实现相关的操作
        // 1.获取源 Bean 对象的所有字段
        Field[] sourceFields = sourceBeanClass.getDeclaredFields();

        // 2.循环遍历源 Bean 对象的所有字段
        for (Field sourceField : sourceFields) {
            // 3.获取源 Bean 对象的某个字段数据
            sourceField.setAccessible(true);
            try {
                Object sourceFieldData = sourceField.get(sourceBean);

                // 4.获取源 Bean 对象的某个字段的名称
                String sourceFieldName = sourceField.getName();

                // 5.获取目标 Bean 对象对应的 Filed 对象
                Field targetField = targetBeanClass.getDeclaredField(sourceFieldName);

                // 6.开放权限
                targetField.setAccessible(true);

                // 7.拷贝赋值
                targetField.set(targetBean, sourceFieldData);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (NoSuchFieldException e) {
                throw new RuntimeException("未知字段", e);
            }
        }
    }
}
